{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Python中类方法的第一个参数以self开始\n",
    "from collections import namedtuple\n",
    "from collections import OrderedDict\n",
    "from functools import reduce\n",
    "import tushare as ts\n",
    "import numpy as np\n",
    "\n",
    "class StockTradeDays(object):\n",
    "    def __init__(self, price_array, start_date, date_array=None):\n",
    "        #私有价格，日期，涨跌幅序列\n",
    "        self.__price_array = price_array\n",
    "        self.__date_array = self._init_days(start_date, date_array)\n",
    "        self.__change_array = self.__init_change()\n",
    "        #进行OrderedDict的组装\n",
    "        self.stock_dict = self._init_stock_dict()\n",
    "        \n",
    "    def __init_change(self):\n",
    "        '''\n",
    "        从Price_array生成change_array\n",
    "        :return:\n",
    "        '''\n",
    "        price_float_array = [float(price_str) for price_str in self.__price_array]\n",
    "        \n",
    "        #前后两日的收盘价格组合成序列\n",
    "        pp_array = [(price1,price2) for price1, price2 in zip(price_float_array[:-1],price_float_array[1:])]\n",
    "        change_array = list(map(lambda pp: reduce(lambda a,b: round((b-a)/a,3),pp),pp_array))\n",
    "        \n",
    "        change_array.insert(0,0)\n",
    "        return change_array\n",
    "    \n",
    "    def _init_days(self, start_date, date_array):\n",
    "        '''\n",
    "        protect方法\n",
    "        :param start_date：初始日期\n",
    "        :para date_array: 给定日期序列\n",
    "        :return:\n",
    "        '''\n",
    "        if date_array is None:\n",
    "            date_array = [str(start_date + ind) for ind, _ in enumerate(self.__price_array)]\n",
    "        else:\n",
    "            date_array = [str(date) for date in date_array]\n",
    "        return date_array\n",
    "    \n",
    "    def _init_stock_dict(self):\n",
    "        # '''\n",
    "        #使用namedtuple, OrderedDict将结果合并\n",
    "        #：return:\n",
    "        #'''\n",
    "        stock_namedtuple = namedtuple('stock',('date','price','change'))\n",
    "        stock_dict = OrderedDict((date, stock_namedtuple(date,price,change))\n",
    "                                 for date, price, change in zip(self.__date_array, self.__price_array,self.__change_array))\n",
    "        return stock_dict\n",
    "    \n",
    "    def filter_stock(self, want_up = True, want_calc_sum = False):\n",
    "        '''\n",
    "        筛选结果子集\n",
    "        :param want_up：True筛选上涨；False筛选下跌\n",
    "        :para want_calc_sum: 是否计算涨跌幅\n",
    "        :return:\n",
    "        '''\n",
    "        filter_func = (lambda day:day.change>0) if want_up else(lambda day: day.change<0 )\n",
    "        want_days = filter(filter_func, self.stock_dict.values())\n",
    "        if not want_calc_sum:\n",
    "            return want_days\n",
    "        change_sum = 0.0\n",
    "        for day in want_days:\n",
    "            change_sum +=day.change\n",
    "        return change_sum\n",
    "    \n",
    "    #其它的函数\n",
    "    def __str__(self):\n",
    "        return str(self.stock_dict)\n",
    "    __repr__ = __str__\n",
    "    \n",
    "    def __iter__(self):\n",
    "        for key in self.stock_dict:\n",
    "            yield self.stock_dict[key]\n",
    "            \n",
    "    def __getitem__(self, ind):\n",
    "        date_key = self.__date_array[ind]\n",
    "        return self.stock_dict[date_key]\n",
    "    \n",
    "    def __len__(self):\n",
    "        #print('i am here')\n",
    "        return len(self.stock_dict)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "import six\n",
    "from abc import ABCMeta, abstractmethod\n",
    "\n",
    "class TradeStrategyBase(six.with_metaclass(ABCMeta, object)):\n",
    "    '''\n",
    "    交易策略抽象基类\n",
    "    '''\n",
    "    @abstractmethod\n",
    "    def buy_strategy(self, *args, **kwargs):\n",
    "        #买入策略基类\n",
    "        pass\n",
    "    @abstractmethod\n",
    "    def sell_strategy(self, *args, **kwargs):\n",
    "        #卖出策略基类\n",
    "        pass\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TradeStrategy1(TradeStrategyBase):\n",
    "    '''\n",
    "    交易策略1：追涨策略，当股价上涨一个阈值默认为7%时\n",
    "    买入股票并持有20天\n",
    "    '''\n",
    "    s_keep_stock_threshold = 2\n",
    "    \n",
    "    def __init__(self):\n",
    "        self.keep_stock_day = 0\n",
    "        self.__buy_change_threshold = 0.005\n",
    "    \n",
    "    def buy_strategy(self, trade_ind, trade_day, trade_days):\n",
    "        if self.keep_stock_day ==0 and trade_day.change>self.__buy_change_threshold:\n",
    "            self.keep_stock_day +=1\n",
    "        elif self.keep_stock_day > 0:\n",
    "            self.keep_stock_day +=1\n",
    "    \n",
    "    def sell_strategy(self, trade_ind, trade_day, trade_days):\n",
    "        if self.keep_stock_day >= TradeStrategy1.s_keep_stock_threshold:\n",
    "            self.keep_stock_day = 0\n",
    "    \n",
    "    @property\n",
    "    def buy_change_threshold(self):\n",
    "        return self.__buy_change_threshold\n",
    "    \n",
    "    @buy_change_threshold.setter\n",
    "    def buy_change_threshold(self, buy_change_threshold):\n",
    "        if not isinstance(buy_change_threshold, float):\n",
    "            raise TypeError('buy_change_threshold must be float')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TradeLoopBack(object):\n",
    "    '''\n",
    "    交易回测系统\n",
    "    '''\n",
    "    def __init__(self, trade_days, trade_strategy):\n",
    "        '''\n",
    "        param trade_days: StockTradeDays 交易数据序列\n",
    "        param trade_strategy: TradeStrategyBase 交易策略\n",
    "        '''\n",
    "        self.trade_days = trade_days\n",
    "        self.trade_strategy = trade_strategy\n",
    "        \n",
    "        self.profit_array = []\n",
    "        #print('==init==')\n",
    "        \n",
    "    def execute_trade(self):\n",
    "        for ind, day in enumerate(self.trade_days):\n",
    "            if self.trade_strategy.keep_stock_day > 0:\n",
    "                self.profit_array.append(day.change)\n",
    "                #print('1')\n",
    "                \n",
    "            if hasattr(self.trade_strategy, 'buy_strategy'):\n",
    "                self.trade_strategy.buy_strategy(ind, day, self.trade_days)\n",
    "                #print('2')\n",
    "                \n",
    "            if hasattr(self.trade_strategy, 'sell_strategy'):\n",
    "                self.trade_strategy.sell_strategy(ind, day, self.trade_days)\n",
    "                #print('3')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "回测策略总体盈亏为：-6.3%\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x216806ec940>]"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x2168065a4e0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from functools import reduce\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "#获取股票历史行情数据\n",
    "stock_code = '002241'\n",
    "stock_array = ts.get_k_data(stock_code, start='2018-06-01')\n",
    "#print(stock_array.values)\n",
    "#print(stock_array.name)\n",
    "\n",
    "#print(stock_code,'的行情数据为:\\n',stock_array)\n",
    "\n",
    "#date_array = [str(date) for date in date_array]\n",
    "\n",
    "date_list = [date for date in stock_array.date]\n",
    "\n",
    "price_array = [price for price in stock_array.close]\n",
    "\n",
    "#print(date_list,'\\n',price_array)\n",
    "\n",
    "real_test = StockTradeDays(price_array,20180601,date_list)\n",
    "#print(list(real_test))\n",
    "trade_loop_back = TradeLoopBack(real_test, TradeStrategy1())\n",
    "trade_loop_back.execute_trade()\n",
    "#reduce(lambda a,b: a+b, trade_loop_back.profit_array)\n",
    "print('回测策略总体盈亏为：{0}%'.format(round(reduce(lambda a,b: a+b, trade_loop_back.profit_array)*100,3)))\n",
    "\n",
    "plt.plot(np.array(trade_loop_back.profit_array).cumsum())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
